package network.chat.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public final class Server extends Thread {

	private final String id;
	private final int port;
	private int numberMaxClient;
	private static ArrayList<Socket> listSocketToClient;
	private static int countServer = 1;

	private final int NB_MAX_CLIENT = 100;

	public Server() {
		this.id = "Anonymous";
		this.port = 2501;
		numberMaxClient = NB_MAX_CLIENT;
		listSocketToClient = new ArrayList<Socket>();
	}

	public Server(String id, int port) {
		this.id = id;
		this.port = port;
		numberMaxClient = NB_MAX_CLIENT;
		listSocketToClient = new ArrayList<Socket>();
	}

	public Server(String id, int port, int nbMaxClient) {
		this.id = id;
		this.port = port;
		this.numberMaxClient = nbMaxClient;
		listSocketToClient = new ArrayList<Socket>();
	}

	public int getNumberOfClient() {
		return listSocketToClient.size();
	}

	@Override
	public String toString() {
		String description = "[ID: " + id + "|" + "NB_CLIENT: " + countServer
				+ "|" + "PORT: " + port + "]";
		return description;
	}

	@Override
	public void run() {
		try {
			ServerSocket socketService = new ServerSocket(port);
			while (true) {
				if (listSocketToClient.size() > numberMaxClient)
					return;
				System.out.print(this.toString() + "\n"
						+ "is waiting for connections... "); // sysout
				Socket socketClient = socketService.accept();
				System.out.println("... connection established from :"
						+ socketClient.getInetAddress()); // sysout
				listSocketToClient.add(socketClient);
				new Reader(socketClient).start();
				countServer++;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public final class Reader extends Thread {
		private Socket socket;

		private Reader() {
			// TODO Auto-generated constructor stub
		}

		private Reader(Socket socket) {
			this.socket = socket;
		}

		// private synchronized void readWriteSynchro() {
		private synchronized void readWriteSynchro() {
			try {				
				BufferedReader in = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));

				String message = in.readLine();
				System.out.println(id + " has just read : " + " " + message);
				if (message == null) {
					listSocketToClient.remove(socket);
					socket.close();
					socket = null;
					return;
				}
				if (!message.contains("/")) {
					for (Socket sock : listSocketToClient) {
						PrintWriter out = new PrintWriter(
								sock.getOutputStream(), true);
						out.println(message);
					}
				} else {
					String command = message
							.substring(message.indexOf("/") + 1);
					System.out.println("SERVER " + command);
					PrintWriter ackCommand = new PrintWriter(
							socket.getOutputStream(), true);
					ackCommand.println("OK BIEN RECU");
					switch (command) {
					case "quit":
						ackCommand.println("/ackquit");
						listSocketToClient.remove(socket);
						socket = null;
						break;
					default:
						break;
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void run() {
			while (socket != null) {
				readWriteSynchro();
			}
		}
	}

	public static void main(String[] args) {
		new Server("Anonymous", 2501).start();
	}
}
